package platform

import (
	"fmt"
	"log"

	"gitee.com/wangshh_123/cross-pay-go/src/models"

	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// updateBalanceForRoleInTransaction 在事务中根据用户角色更新相应的余额
// 这个函数用于在退款等操作中，确保余额更新在同一个事务中完成
// 角色2（普通用户）：只修改 hlpay_account_balances 表
// 角色3（主账号）：修改 hlpay_account_balances 表和 master_accounts 表
// 角色5（子账号）：修改 hlpay_account_balances 表和 sub_accounts 表
func (c *UnifiedCardController) updateBalanceForRoleInTransaction(tx *gorm.DB, userID int64, roleID int, amount decimal.Decimal, operation string, platformType string, accountNo string) error {
	// 根据操作类型确定是增加还是减少余额
	var updateAmount decimal.Decimal
	switch operation {
	case "deduct", "decrease", "subtract":
		updateAmount = amount.Neg() // 负数表示扣除
	case "add", "increase", "recharge":
		updateAmount = amount // 正数表示增加
	default:
		return fmt.Errorf("不支持的操作类型: %s", operation)
	}

	log.Printf("[updateBalanceForRoleInTransaction] 开始处理余额更新 - 用户ID: %d, 角色ID: %d, 操作: %s, 金额: %s, 平台: %s",
		userID, roleID, operation, amount.String(), platformType)

	// 根据用户角色更新相应的余额
	switch roleID {
	case 2: // 普通用户 - 只修改 hlpay_account_balances 表
		log.Printf("[updateBalanceForRoleInTransaction] 处理普通用户（角色2）余额更新")

		if platformType == "hlpay" {
			// 获取或查找HlPay账户号
			var targetAccountNo string
			if accountNo != "" {
				targetAccountNo = accountNo
			} else {
				// 通过用户ID查找矩阵账户
				var userMatrixAccount models.UserMatrixAccount
				if err := tx.Where("user_id = ? AND platform_type = ?", userID, "hlpay").First(&userMatrixAccount).Error; err != nil {
					return fmt.Errorf("找不到用户对应的矩阵账户: %v", err)
				}

				// 查找对应的HlPay账户余额记录
				var hlpayAccount models.HlPayAccountBalance
				if err := tx.Where("owner_no = ? AND currency = ?", userMatrixAccount.MatrixAccount, "USD").First(&hlpayAccount).Error; err != nil {
					return fmt.Errorf("找不到用户对应的HlPay账户余额记录: %v", err)
				}
				targetAccountNo = hlpayAccount.AccountNo
			}

			// 更新HlPay账户余额
			var account models.HlPayAccountBalance
			if err := tx.Where("account_no = ?", targetAccountNo).First(&account).Error; err != nil {
				return fmt.Errorf("找不到HlPay账户记录: %v", err)
			}

			// 检查余额是否足够（如果是扣除操作）
			if updateAmount.IsNegative() && account.RealTimeBalance.LessThan(amount) {
				return fmt.Errorf("HlPay账户余额不足: %s < %s", account.RealTimeBalance.String(), amount.String())
			}

			newBalance := account.RealTimeBalance.Add(updateAmount)
			if err := tx.Model(&account).Update("real_time_balance", newBalance).Error; err != nil {
				return fmt.Errorf("更新HlPay账户余额失败: %v", err)
			}

			log.Printf("[updateBalanceForRoleInTransaction] 普通用户HlPay账户余额更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
				targetAccountNo, operation, amount.String(), account.RealTimeBalance.String(), newBalance.String())
		} else {
			log.Printf("[updateBalanceForRoleInTransaction] 普通用户，非HlPay平台，跳过余额更新")
		}

	case 3: // 主账号 - 修改 hlpay_account_balances 表和 master_accounts 表
		log.Printf("[updateBalanceForRoleInTransaction] 处理主账号（角色3）余额更新")

		// 1. 更新主账号余额 (master_accounts 表)
		var masterAccount models.MasterAccount
		if err := tx.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			return fmt.Errorf("找不到主账号记录: %v", err)
		}

		log.Printf("[updateBalanceForRoleInTransaction] 主账号信息 - ID: %d, 账户名: %s, 当前余额: %s",
			masterAccount.ID, masterAccount.AccountName, masterAccount.Balance.String())

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && masterAccount.Balance.LessThan(amount) {
			return fmt.Errorf("主账号余额不足: %s < %s", masterAccount.Balance.String(), amount.String())
		}

		newMasterBalance := masterAccount.Balance.Add(updateAmount)
		if err := tx.Model(&masterAccount).Update("balance", newMasterBalance).Error; err != nil {
			return fmt.Errorf("更新主账号余额失败: %v", err)
		}

		log.Printf("[updateBalanceForRoleInTransaction] 主账号余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), masterAccount.Balance.String(), newMasterBalance.String())

		// 2. 如果是HlPay平台，同时更新HlPay账户余额 (hlpay_account_balances 表)
		if platformType == "hlpay" {
			var userMatrixAccount models.UserMatrixAccount
			if err := tx.Where("user_id = ? AND platform_type = ?", userID, "hlpay").First(&userMatrixAccount).Error; err == nil {
				log.Printf("[updateBalanceForRoleInTransaction] 找到主账号对应的矩阵账户: %s", userMatrixAccount.MatrixAccount)

				// 查找对应的HlPay账户余额记录
				var hlpayAccount models.HlPayAccountBalance
				if err := tx.Where("owner_no = ? AND currency = ?", userMatrixAccount.MatrixAccount, "USD").First(&hlpayAccount).Error; err == nil {
					log.Printf("[updateBalanceForRoleInTransaction] 找到HlPay账户余额记录: %s, 当前余额: %s",
						hlpayAccount.AccountNo, hlpayAccount.RealTimeBalance.String())

					// 同步更新HlPay账户余额
					hlpayNewBalance := hlpayAccount.RealTimeBalance.Add(updateAmount)
					if err := tx.Model(&hlpayAccount).Update("real_time_balance", hlpayNewBalance).Error; err != nil {
						return fmt.Errorf("同步更新HlPay账户余额失败: %v", err)
					}

					log.Printf("[updateBalanceForRoleInTransaction] 主账号HlPay账户余额同步更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
						hlpayAccount.AccountNo, operation, amount.String(), hlpayAccount.RealTimeBalance.String(), hlpayNewBalance.String())
				} else {
					log.Printf("[updateBalanceForRoleInTransaction] 未找到主账号对应的HlPay账户余额记录: %v", err)
				}
			} else {
				log.Printf("[updateBalanceForRoleInTransaction] 未找到主账号对应的矩阵账户: %v", err)
			}
		}

	case 5: // 子账号 - 修改 hlpay_account_balances 表和 sub_accounts 表
		log.Printf("[updateBalanceForRoleInTransaction] 处理子账号（角色5）余额更新")

		// 1. 更新子账号余额 (sub_accounts 表)
		var subAccount models.SubAccount
		if err := tx.Where("user_id = ?", userID).First(&subAccount).Error; err != nil {
			return fmt.Errorf("找不到子账号记录: %v", err)
		}

		log.Printf("[updateBalanceForRoleInTransaction] 子账号信息 - ID: %d, 账户名: %s, 主账号ID: %d, 当前余额: %s",
			subAccount.ID, subAccount.AccountName, subAccount.MasterAccountID, subAccount.Balance.String())

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && subAccount.Balance.LessThan(amount) {
			return fmt.Errorf("子账号余额不足: %s < %s", subAccount.Balance.String(), amount.String())
		}

		newSubBalance := subAccount.Balance.Add(updateAmount)
		if err := tx.Model(&subAccount).Update("balance", newSubBalance).Error; err != nil {
			return fmt.Errorf("更新子账号余额失败: %v", err)
		}

		log.Printf("[updateBalanceForRoleInTransaction] 子账号余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), subAccount.Balance.String(), newSubBalance.String())

		// 2. 如果是HlPay平台，同时更新HlPay账户余额 (hlpay_account_balances 表)
		if platformType == "hlpay" {
			var userMatrixAccount models.UserMatrixAccount
			if err := tx.Where("user_id = ? AND platform_type = ?", userID, "hlpay").First(&userMatrixAccount).Error; err == nil {
				log.Printf("[updateBalanceForRoleInTransaction] 找到子账号对应的矩阵账户: %s", userMatrixAccount.MatrixAccount)

				// 查找对应的HlPay账户余额记录
				var hlpayAccount models.HlPayAccountBalance
				if err := tx.Where("owner_no = ? AND currency = ?", userMatrixAccount.MatrixAccount, "USD").First(&hlpayAccount).Error; err == nil {
					log.Printf("[updateBalanceForRoleInTransaction] 找到HlPay账户余额记录: %s, 当前余额: %s",
						hlpayAccount.AccountNo, hlpayAccount.RealTimeBalance.String())

					// 同步更新HlPay账户余额
					hlpayNewBalance := hlpayAccount.RealTimeBalance.Add(updateAmount)
					if err := tx.Model(&hlpayAccount).Update("real_time_balance", hlpayNewBalance).Error; err != nil {
						return fmt.Errorf("同步更新HlPay账户余额失败: %v", err)
					}

					log.Printf("[updateBalanceForRoleInTransaction] 子账号HlPay账户余额同步更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
						hlpayAccount.AccountNo, operation, amount.String(), hlpayAccount.RealTimeBalance.String(), hlpayNewBalance.String())
				} else {
					log.Printf("[updateBalanceForRoleInTransaction] 未找到子账号对应的HlPay账户余额记录: %v", err)
				}
			} else {
				log.Printf("[updateBalanceForRoleInTransaction] 未找到子账号对应的矩阵账户: %v", err)
			}
		}

	default:
		// 对于其他角色，尝试从主账号表更新余额（保持向后兼容）
		log.Printf("[updateBalanceForRoleInTransaction] 处理默认角色（角色ID: %d）余额更新", roleID)

		var masterAccount models.MasterAccount
		if err := tx.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			return fmt.Errorf("找不到主账号记录: %v", err)
		}

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && masterAccount.Balance.LessThan(amount) {
			return fmt.Errorf("主账号余额不足: %s < %s", masterAccount.Balance.String(), amount.String())
		}

		newBalance := masterAccount.Balance.Add(updateAmount)
		if err := tx.Model(&masterAccount).Update("balance", newBalance).Error; err != nil {
			return fmt.Errorf("更新主账号余额失败: %v", err)
		}

		log.Printf("[updateBalanceForRoleInTransaction] 默认角色余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), masterAccount.Balance.String(), newBalance.String())
	}

	log.Printf("[updateBalanceForRoleInTransaction] 余额更新完成 - 用户ID: %d, 角色ID: %d, 操作: %s, 金额: %s",
		userID, roleID, operation, amount.String())

	return nil
}

// updateBalanceForRole 根据用户角色更新相应的余额
// 这个函数确保在涉及资金操作时正确处理不同角色的余额更新
// 角色2（普通用户）：只修改 hlpay_account_balances 表
// 角色3（主账号）：修改 hlpay_account_balances 表和 master_accounts 表
// 角色5（子账号）：修改 hlpay_account_balances 表和 sub_accounts 表
func (c *UnifiedCardController) updateBalanceForRole(ctx *gin.Context, userID int64, roleID int, amount decimal.Decimal, operation string, platformType string, accountNo string) error {
	// 开始事务
	tx := c.db.Begin()
	if tx.Error != nil {
		return fmt.Errorf("开始事务失败: %v", tx.Error)
	}

	// 根据操作类型确定是增加还是减少余额
	var updateAmount decimal.Decimal
	switch operation {
	case "deduct", "decrease", "subtract":
		updateAmount = amount.Neg() // 负数表示扣除
	case "add", "increase", "recharge":
		updateAmount = amount // 正数表示增加
	default:
		tx.Rollback()
		return fmt.Errorf("不支持的操作类型: %s", operation)
	}

	log.Printf("[updateBalanceForRole] 开始处理余额更新 - 用户ID: %d, 角色ID: %d, 操作: %s, 金额: %s, 平台: %s",
		userID, roleID, operation, amount.String(), platformType)

	// 根据用户角色更新相应的余额
	switch roleID {
	case 2: // 普通用户 - 只修改 hlpay_account_balances 表
		log.Printf("[updateBalanceForRole] 处理普通用户（角色2）余额更新")

		if platformType == "hlpay" {
			// 获取或查找HlPay账户号
			var targetAccountNo string
			if accountNo != "" {
				targetAccountNo = accountNo
			} else {
				// 通过用户ID查找矩阵账户
				var userMatrixAccount models.UserMatrixAccount
				if err := tx.Where("user_id = ? AND platform_type = ?", userID, "hlpay").First(&userMatrixAccount).Error; err != nil {
					tx.Rollback()
					return fmt.Errorf("找不到用户对应的矩阵账户: %v", err)
				}

				// 查找对应的HlPay账户余额记录
				var hlpayAccount models.HlPayAccountBalance
				if err := tx.Where("owner_no = ? AND currency = ?", userMatrixAccount.MatrixAccount, "USD").First(&hlpayAccount).Error; err != nil {
					tx.Rollback()
					return fmt.Errorf("找不到用户对应的HlPay账户余额记录: %v", err)
				}
				targetAccountNo = hlpayAccount.AccountNo
			}

			// 更新HlPay账户余额
			var account models.HlPayAccountBalance
			if err := tx.Where("account_no = ?", targetAccountNo).First(&account).Error; err != nil {
				tx.Rollback()
				return fmt.Errorf("找不到HlPay账户记录: %v", err)
			}

			// 检查余额是否足够（如果是扣除操作）
			if updateAmount.IsNegative() && account.RealTimeBalance.LessThan(amount) {
				tx.Rollback()
				return fmt.Errorf("HlPay账户余额不足: %s < %s", account.RealTimeBalance.String(), amount.String())
			}

			newBalance := account.RealTimeBalance.Add(updateAmount)
			if err := tx.Model(&account).Update("real_time_balance", newBalance).Error; err != nil {
				tx.Rollback()
				return fmt.Errorf("更新HlPay账户余额失败: %v", err)
			}

			log.Printf("[updateBalanceForRole] 普通用户HlPay账户余额更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
				targetAccountNo, operation, amount.String(), account.RealTimeBalance.String(), newBalance.String())
		} else {
			log.Printf("[updateBalanceForRole] 普通用户，非HlPay平台，跳过余额更新")
		}

	case 3: // 主账号 - 修改 hlpay_account_balances 表和 master_accounts 表
		log.Printf("[updateBalanceForRole] 处理主账号（角色3）余额更新")

		// 1. 更新主账号余额 (master_accounts 表)
		var masterAccount models.MasterAccount
		if err := tx.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("找不到主账号记录: %v", err)
		}

		log.Printf("[updateBalanceForRole] 主账号信息 - ID: %d, 账户名: %s, 当前余额: %s",
			masterAccount.ID, masterAccount.AccountName, masterAccount.Balance.String())

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && masterAccount.Balance.LessThan(amount) {
			tx.Rollback()
			return fmt.Errorf("主账号余额不足: %s < %s", masterAccount.Balance.String(), amount.String())
		}

		newMasterBalance := masterAccount.Balance.Add(updateAmount)
		if err := tx.Model(&masterAccount).Update("balance", newMasterBalance).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("更新主账号余额失败: %v", err)
		}

		log.Printf("[updateBalanceForRole] 主账号余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), masterAccount.Balance.String(), newMasterBalance.String())

		// 2. 如果是HlPay平台，同时更新HlPay账户余额 (hlpay_account_balances 表)
		if platformType == "hlpay" {
			var userMatrixAccount models.UserMatrixAccount
			if err := tx.Where("user_id = ? AND platform_type = ?", userID, "hlpay").First(&userMatrixAccount).Error; err == nil {
				log.Printf("[updateBalanceForRole] 找到主账号对应的矩阵账户: %s", userMatrixAccount.MatrixAccount)

				// 查找对应的HlPay账户余额记录
				var hlpayAccount models.HlPayAccountBalance
				if err := tx.Where("owner_no = ? AND currency = ?", userMatrixAccount.MatrixAccount, "USD").First(&hlpayAccount).Error; err == nil {
					log.Printf("[updateBalanceForRole] 找到HlPay账户余额记录: %s, 当前余额: %s",
						hlpayAccount.AccountNo, hlpayAccount.RealTimeBalance.String())

					// 同步更新HlPay账户余额
					hlpayNewBalance := hlpayAccount.RealTimeBalance.Add(updateAmount)
					if err := tx.Model(&hlpayAccount).Update("real_time_balance", hlpayNewBalance).Error; err != nil {
						tx.Rollback()
						return fmt.Errorf("同步更新HlPay账户余额失败: %v", err)
					}

					log.Printf("[updateBalanceForRole] 主账号HlPay账户余额同步更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
						hlpayAccount.AccountNo, operation, amount.String(), hlpayAccount.RealTimeBalance.String(), hlpayNewBalance.String())
				} else {
					log.Printf("[updateBalanceForRole] 未找到主账号对应的HlPay账户余额记录: %v", err)
				}
			} else {
				log.Printf("[updateBalanceForRole] 未找到主账号对应的矩阵账户: %v", err)
			}
		}

	case 5: // 子账号 - 修改 hlpay_account_balances 表和 sub_accounts 表
		log.Printf("[updateBalanceForRole] 处理子账号（角色5）余额更新")

		// 1. 更新子账号余额 (sub_accounts 表)
		var subAccount models.SubAccount
		if err := tx.Where("user_id = ?", userID).First(&subAccount).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("找不到子账号记录: %v", err)
		}

		log.Printf("[updateBalanceForRole] 子账号信息 - ID: %d, 账户名: %s, 主账号ID: %d, 当前余额: %s",
			subAccount.ID, subAccount.AccountName, subAccount.MasterAccountID, subAccount.Balance.String())

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && subAccount.Balance.LessThan(amount) {
			tx.Rollback()
			return fmt.Errorf("子账号余额不足: %s < %s", subAccount.Balance.String(), amount.String())
		}

		newSubBalance := subAccount.Balance.Add(updateAmount)
		if err := tx.Model(&subAccount).Update("balance", newSubBalance).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("更新子账号余额失败: %v", err)
		}

		log.Printf("[updateBalanceForRole] 子账号余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), subAccount.Balance.String(), newSubBalance.String())

		// 2. 如果是HlPay平台，同时更新HlPay账户余额 (hlpay_account_balances 表)
		if platformType == "hlpay" {
			var userMatrixAccount models.UserMatrixAccount
			if err := tx.Where("user_id = ? AND platform_type = ?", userID, "hlpay").First(&userMatrixAccount).Error; err == nil {
				log.Printf("[updateBalanceForRole] 找到子账号对应的矩阵账户: %s", userMatrixAccount.MatrixAccount)

				// 查找对应的HlPay账户余额记录
				var hlpayAccount models.HlPayAccountBalance
				if err := tx.Where("owner_no = ? AND currency = ?", userMatrixAccount.MatrixAccount, "USD").First(&hlpayAccount).Error; err == nil {
					log.Printf("[updateBalanceForRole] 找到HlPay账户余额记录: %s, 当前余额: %s",
						hlpayAccount.AccountNo, hlpayAccount.RealTimeBalance.String())

					// 同步更新HlPay账户余额
					hlpayNewBalance := hlpayAccount.RealTimeBalance.Add(updateAmount)
					if err := tx.Model(&hlpayAccount).Update("real_time_balance", hlpayNewBalance).Error; err != nil {
						tx.Rollback()
						return fmt.Errorf("同步更新HlPay账户余额失败: %v", err)
					}

					log.Printf("[updateBalanceForRole] 子账号HlPay账户余额同步更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
						hlpayAccount.AccountNo, operation, amount.String(), hlpayAccount.RealTimeBalance.String(), hlpayNewBalance.String())
				} else {
					log.Printf("[updateBalanceForRole] 未找到子账号对应的HlPay账户余额记录: %v", err)
				}
			} else {
				log.Printf("[updateBalanceForRole] 未找到子账号对应的矩阵账户: %v", err)
			}
		}

	default:
		// 对于其他角色，尝试从主账号表更新余额（保持向后兼容）
		log.Printf("[updateBalanceForRole] 处理默认角色（角色ID: %d）余额更新", roleID)

		var masterAccount models.MasterAccount
		if err := tx.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("找不到主账号记录: %v", err)
		}

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && masterAccount.Balance.LessThan(amount) {
			tx.Rollback()
			return fmt.Errorf("主账号余额不足: %s < %s", masterAccount.Balance.String(), amount.String())
		}

		newBalance := masterAccount.Balance.Add(updateAmount)
		if err := tx.Model(&masterAccount).Update("balance", newBalance).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("更新主账号余额失败: %v", err)
		}

		log.Printf("[updateBalanceForRole] 默认角色余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), masterAccount.Balance.String(), newBalance.String())
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		return fmt.Errorf("提交事务失败: %v", err)
	}

	log.Printf("[updateBalanceForRole] 余额更新完成 - 用户ID: %d, 角色ID: %d, 操作: %s, 金额: %s",
		userID, roleID, operation, amount.String())

	return nil
}
